/**   
 * Copyright 2011 COMERE Harold
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package etrl.shaders;

/**
 * \class Variable
 * \brief Abstract class to represent different kinds of glsl variables
 * @author harold
 *
 */
public abstract class Variable
{
	/**
	 * \brief The variable name
	 */
	protected String _name;

	/**
	 * \brief The variable glsl type
	 */
	protected GLSLType _type;

	/**
	 * \brief The variable forward mode
	 */
	protected VariableForwardMode _forwardMode;

	/**
	 * \brief Allowing modifiers flag.
	 * If true, the variable can be modified, else not
	 */
	private boolean _allowModifiers;
	
	/**
	 * \brief Binding needed flag.
	 * If true the variable needs a specific binding, else not
	 */
	private boolean _needBinding;

	/**
	 * \brief Array flag
	 * If true, the variable is an array, else not
	 */
	protected boolean _array;

	/**
	 * \brief Array size, only valid if _array == true
	 */
	protected int _arraySize;

	/**
	 * \brief Initializes the variable
	 * @param[in] name Name of the variable
	 * @param[in] type Glsl type of the variable
	 * @param[in] forwardMode Forward mode of the variable
	 * @param[in] modifiable Allowing modifier flag
	 * @param[in] needBinding Needing binding flag
	 * @param[in] elementCount Element count of the variable, if > 1 the variable is an array
	 */
	public Variable(String name, GLSLType type, VariableForwardMode forwardMode, boolean modifiable, boolean needBinding, int elementCount)
	{
		_name = name;
		_type = type;
		_forwardMode = forwardMode;
		_allowModifiers = modifiable;
		_needBinding = needBinding;
		_arraySize = elementCount;
		_array = (elementCount > 1);
	}

	/**
	 * \brief Checks if the variable allows modifiers
	 * @return true if the variable allows modifiers, else false
	 */
	public boolean allowModifiers()
	{
		return _allowModifiers;
	}

	/**
	 * \brief Checks if the variable needs a binding
	 * @return true if the variable needs a binding, else false
	 */
	public boolean needBinding()
	{
		return _needBinding;
	}

	/**
	 * \brief Gets the variable name
	 * @return Variable name
	 */
	public String getName()
	{
		return _name;
	}
	
	/**
	 * \brief Gets the variable name with its array mark
	 * @return Variable name with array mark
	 */
	public String getNameWithArrayMark()
	{
		String nameWithArrayMark = getName();
		if(_array)
			nameWithArrayMark += "[" + _arraySize + "]";
		return nameWithArrayMark;
	}

	/**
	 * \brief Gets the variable glsl type
	 * @return Variable glsl type
	 */
	public GLSLType getType()
	{
		return _type;
	}

	/**
	 * \brief Gets the variable declaration in vertex shader
	 * @return Variable declaration
	 */
	public abstract String getDeclarationInVertexShader();

	/**
	 * \brief Gets the variable declaration in fragment shader
	 * @return Variable declaration
	 */
	public abstract String getDeclarationInFragmentShader();

	/**
	 * \brief Gets the variable initialization
	 * @return Variable initialization
	 */
	public abstract String getInitialization();

	/**
	 * \brief Gets the variable binding id
	 * @return Binding id
	 */
	public abstract String getBindingId();

	/**
	 * Gets the variable name with prefix
	 * @param[in] stage Current shader stage 
	 * @return Variable name with prefix
	 */
	public abstract String nameWithPrefix(ShaderStage stage);
}
